﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RpcClient;
using RpcHelper;
using RpcModel;
using Wedonek.RpcStore.Gateway.Interface;
using Wedonek.RpcStore.Gateway.Model;
using Wedonek.RpcStore.Service.Interface;
using Wedonek.RpcStore.Service.Model;

namespace Wedonek.RpcStore.Gateway.Service
{
        internal class BroadcastLogService : IBroadcastLogService
        {
                private readonly IBroadcastLogCollect _Broadcast;
                private readonly IRpcMerCollect _RpcMer;
                private readonly IServerCollect _Server;
                private readonly IErrorLangMsgCollect _ErrorMsg;
                private readonly IErrorCollect _Error;
                public BroadcastLogService (IBroadcastLogCollect broadcast,
                        IServerCollect server,
                        IErrorCollect error,
                        IRpcMerCollect rpcMer,
                        IErrorLangMsgCollect errorMsg)
                {
                        this._RpcMer = rpcMer;
                        this._Error = error;
                        this._Server = server;
                        this._ErrorMsg = errorMsg;
                        this._Broadcast = broadcast;
                }
                public BroadcastErrorLogData Get (Guid id)
                {
                        return this._Broadcast.Get (id);
                }
                private Dictionary<long, string> _GetErrors (long[] errorId)
                {
                        Dictionary<long, string> errors = new Dictionary<long, string> ();
                        if (errorId.Length > 0)
                        {
                                ErrorDatum[] er = this._Error.Gets (errorId);
                                er.ForEach (a => errors.Add (a.Id, a.ErrorCode));
                                errorId = er.Convert (c => c.IsPerfect, c => c.Id);
                                if (errorId.Length > 0)
                                {
                                        ErrorLang[] langs = this._ErrorMsg.GetErrorMsg (errorId);
                                        langs.ForEach (a => errors[a.ErrorId] = a.Msg);
                                }
                        }
                        return errors;
                }
                public BroadcastLog[] Query (BroadcastQueryParam query, IBasicPage paging, out long count)
                {
                        BroadcastErrorLog[] logs = this._Broadcast.Query (query, paging, out count);
                        if (logs.Length == 0)
                        {
                                return null;
                        }
                        Dictionary<long, string> errors = this._GetErrors (logs.Distinct (a => a.ErrorCode));
                        BasicService[] services = this._Server.GetBasic (logs.Distinct (a => a.ServerId != 0, a => a.ServerId));
                        BasicRpcMer[] mers = this._RpcMer.GetBasic (logs.Distinct (a => a.RpcMerId != 0, a => a.RpcMerId));
                        return logs.ConvertMap<BroadcastErrorLog, BroadcastLog> ((a, b) =>
                        {
                                if (a.ErrorCode != 0)
                                {
                                        b.Error = errors.GetValueOrDefault(a.ErrorCode,string.Empty);
                                }
                                if (a.RpcMerId != 0)
                                {
                                        b.RpcMer = mers.Find (c => c.Id == a.RpcMerId, c => c.SystemName);
                                }
                                if (a.ServerId != 0)
                                {
                                        b.ServerName = services.Find (c => c.Id == a.ServerId, c => c.ServerName);
                                }
                                return b;
                        });
                }
        }
}
